. In the release of System File version 4.1 for the Macintosh, routines were added to facilitate the use of hierarchial menus. This file will attempt to describe how to use them, using techniques I discovered by "reverse engineering" a demonstration program Apple released to show off their new addition to the system file. No guarantees concerning the accuracy of the information will be made.
NOMENCLATURE ++>
Hierarchial menu: A sub-menu connected to a certain menu item. It is
displayed if the mouse pointer is held over a parent item for a short period
of time.
Parent menu: The menu to which a parent item belongs.
Parent item: All hierarchial menus must belong to a certain item in a
connecting menu. This item, when selected, causes the hierarchial menu
indicated in character marking item field of the currently selected menu item
to be called up and displayed on the screen.
Child menu: A hierarchial menu; a menu connected to an item in a previous
menu.
. When using hierarchial menus, there are a few things to keep in mind:
o All hierarchial menu must "belong" to a regular old-style menu which is
connected to the the menu bar.
o All hierarchial menus must have a resource ID in the range of $F6 to $FF
inclusive (246 to 255 decimal).
o The title of all hierarchial menus must be three bytes long, the first two
bytes being '$F' and the last being the hex digit corresponding to the last
number in the resource ID of the hierarchial menu. For example, a
hierarchial menu with resource ID number 246 would have the title of '$F6'.
o Hierarchial menus are linked to menu items in the parent menu through the
character marking item field of a menu item. Say that, for some reason, you
wish to connect a hierarchial menu with resource number 255 to a certain
item in a particular menu in your program; just change the character marking
item number from 0 (the standard value) to 255.
HIERARCHIAL MENU RESOURCES ++>
. The structure of resource files for hierarchial menus is just the same for other menus other than the name and numbering method described above. Connecting the menus in a hierarchial manner can prove a little tricky but not really difficult. First, to create a parent menu, you must have at least one item in the menu which is connected to a child menu through little "flags" in the menu item definition. These flags are set up as follows:
o The text field of the menu item must be terminated by the hex value of $C9
(201 decimal).
o The keyboard equivalent field must be set to $1B (27 decimal), commonly
known as the ESCAPE key.
o The character marking item field must hold the resource ID number of the
child menu. Remember the value must be in the range of $F6 to $FF (246 to
255 decimal).
INSERTING HIERARCHIAL MENUS INTO THE MENU BAR ++>
. To insert hierarchial menu, insert all other normal menus first. After this is done, insert all the hierarchial menus, connecting them to their parents by using following InsertMenu call (the specifics of the connection are handled by the computer):
--> InsertMenu(MenuHandle,-1); (* Insert hierarchial menu *)
. Note: Then -1 value seems to be significant in some way, otherwise the InsertMenu call is standard. Of course, after everything is placed into the menu, don't forget to the draw the menu bar (DrawMenuBar).
DEALING WITH ITEMS SELECTED IN HIERARCHIAL MENUS ++>
. Item selections are dealt with in the same way as regular menu item selections. When a FindWindow call tells you there has been a menu selection, the Event Manager message will contain the resource ID of the selected menu. If the selection has been in a hierarchial menu, then the resource ID will be within the hierarchial menu resource ID range and you should deal with it accordingly.
USING HIERARCHIAL MENUS WISELY ++>
. I have noticed that there is a certain temptation for the programmer to use hierarchial menus whenever physically possible. However, I think this would probably be somewhat confusing to the average user. The wisest course of action would be to use them only as necessary, such as when the menu is running out of room, especially when it contains items that contain a common theme which would allow them to be grouped in a separate sub-menu. The example which comes most easily to mind would be the font style menu for most graphics and word processor programs. When in doubt, use regular menus.
. As a programming aid, I am including the decompiled menu resource from Apple's DAMenus demonstration program. Here it is, using the C structure format used in the ResTools resource decompiler:
(* Note: The resource numbers in the header of each resource (except for the first), are different than the resource IDs in the body of the definition because of the structure of the owned resources in the desk accessory to which they belonged *)
resource 'MENU' (-16000)
{
-16000,
0,
0x7fffffbb,
disabled,
"DAMenu Tester",
{
"About DAMenu\0xc9", 0, 0, 0, 0;
"-", 0, 0, 0, 0;
"To Level 2\0xc9", 0, 27, 246, 0;
"Item 1-A", 0, 65, 0, 0;
"Item 1-B", 0, 66, 0, 0;
"-", 0, 0, 0, 0;
"Quit", 0, 81, 0, 0
}
};
resource 'MENU' (-15999)
{
246,
0,
0x7fffff6b,
disabled,
"$F6",
{
"Item 2-C", 0, 0, 0, 0;
"-", 0, 0, 0, 0;
"To Level 3a\0xc9", 0, 27, 247, 0;
"-", 0, 0, 0, 0;
"Item 2-D", 0, 0, 0, 0;
"Item 2-E", 0, 0, 0, 0;
"-", 0, 0, 0, 0;
"To Level 3b\0xc9", 0, 27, 248, 0
}
};
resource 'MENU' (-15998)
{
247,
0,
0x7fffffff,
disabled,
"$F7",
{
"Item 3a-F", 0, 0, 0, 0;
"Item 3a-G", 0, 0, 0, 0
}
};
resource 'MENU' (-15997)
{
248,
0,
0x7fffffff,
disabled,
"$F8",
{
"Item 3b-H", 0, 0, 0, 0;
"Item 3b-I", 0, 0, 0, 0
}
};
. If you have any questions, or would like to point out any inaccuracies, please contact me on CompuServe at user ID number 74055,1121. Distribute this file freely to any information service or bulletin board.